#include <allegro.h>
#include <stdio.h>
#include <time.h>

#define GFX_W 900
#define GFX_H 620
#define NB_IMAGES 3

typedef struct
{ int x;
  int y;
 
  BITMAP * img_right[NB_IMAGES];
  BITMAP * img_left[NB_IMAGES];
  int direction; // 0: right 1:left 2:up 
}Personnage;

typedef struct
{
int x,y,w,h;
}variable;


typedef struct
{
 int x;
 int y;
BITMAP *image;
BITMAP *image1;
int affiche;

} epine;



//utils
int get_pixel(BITMAP* Buffer,int x,int y);


//Module Background
BITMAP* load_background_bmp(char chemin_background[]);
void draw_background(BITMAP *Background,BITMAP*Buffer,int j);
void destroy_background(BITMAP * Background);

//Module grace
void load_grace(Personnage *p);
void destroy_grace(Personnage *p);
void init_grace(Personnage *p);

void move_grace_right(Personnage *p,int *compteur,BITMAP * Background,int *j,int *move);
void move_grace_left(Personnage *p,int *compteur,BITMAP * Background,int j);
void jump_grace(Personnage *p,BITMAP * Background,int j,int *test); //move up

void gravity_grace(Personnage *p,BITMAP * Background,int j);


void move_grace(Personnage *p,int *compteur,BITMAP * Background, int *j,int * move,int *test);
void draw_grace(Personnage p,BITMAP *Buffer, int compteur);


int collision_background_right(variable v,BITMAP* BackgroundCol,int o);
int collision_background_left(variable v,BITMAP* BackgroundCol,int o);
int collision_background_down(variable v,BITMAP* BackgroundCol, int o);
int collision_background_up(variable v,BITMAP* BackgroundCol, int o);

int collision(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2);
void soundm();

int main()
{int o;
variable v;

int score=0;

epine epine,epine2,epine3,epine4,epine5;
epine.x=1050;
epine.y=230;



epine2.x=3250;
epine2.y=210;

epine3.x=2550;
epine3.y=210;

epine5.x=2550;
epine5.y=490;

epine3.affiche=0;
epine5.affiche=0;
int dead=0;
int move=0;

int vie=3;
int test=1;

int en=200;
int i=0;
	//background
	
	char chemin_background[]="./Pictures/foret.bmp";
	char chemin_background2[]="./Pictures/foretblanc.bmp";


	BITMAP *Buffer;
	BITMAP *Background=NULL;
	BITMAP *BackgroundCol=NULL;

 	
	int j=0;// Pour le deplacement du background, il est incrementé plusieurs fois jusqu'a la fin du niveau 

	Personnage p;
       
	int compteur;

	/* General initialization function */
	allegro_init();
	if (install_keyboard() == -1) {
		allegro_message("Error! %s", allegro_error);
		return (-1);
	}
	set_color_depth(24);
	if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, GFX_W, GFX_H, 0, 0) != 0) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); /* here’s the command for text mode */
		allegro_message("Unable to initialize video mode!\n%s\n", allegro_error);
		return (1);
	}
	
	Buffer = create_bitmap(SCREEN_W, SCREEN_H);
	
	//loading images
	//loading grace
	load_grace(&p);

	epine.image=load_bitmap("./Pictures/epine.bmp", NULL);	
	epine.image1=load_bitmap("./Pictures/epine5.bmp", NULL);	
	
	//loading background + background collision
	Background=load_background_bmp(chemin_background);
	BackgroundCol=load_background_bmp(chemin_background2);

	//init position & direction
	compteur = 0;
	init_grace(&p);

	//soundm();
	
	while (!key[KEY_ESC])
{



		//vider le buffer
		clear_bitmap(Buffer);
		//moving grace
		move_grace(&p,&compteur,BackgroundCol,&j,&move,&test);

		//drawing background		
		draw_background(Background,Buffer,j);
               
		//drawing grace
		draw_grace(p,Buffer,compteur);
		textprintf_ex(Buffer, font, 300, 30, makecol(0,0,0),-1, " TEMPS: %f s", (float)clock()/CLOCKS_PER_SEC);
		textprintf_ex(Buffer,font,10,45,makecol(0,0,0),-1,"VIE: %d ",vie);
		textprintf_ex(Buffer,font,10,30,makecol(236,15,75),-1,"ENERGIE: %d ",en);

		textprintf_ex(Buffer,font,150,30,makecol(0,0,255),-1,"SCORE: %d ",score);

  		draw_sprite(Buffer, epine.image, epine.x,epine.y);
		draw_sprite(Buffer, epine.image, epine2.x,epine2.y);
		

if(epine3.affiche==1)
{draw_sprite(Buffer, epine.image, epine3.x,epine3.y);
 
} 

if(epine5.affiche==1)
{draw_sprite(Buffer, epine.image1, epine5.x,epine5.y);
 
}

if( (j<Background->w - SCREEN_W && j>=1000) && move!= 1)
{
  epine3.affiche=1;
}

if( (j<Background->w - SCREEN_W && j>=1000) && move== 1)
{
  epine3.affiche=1;
  epine3.x=epine3.x-3;
}


if( (j<Background->w - SCREEN_W && j>=1000) && move!= 1)
{
  epine5.affiche=1;
}

if( (j<Background->w - SCREEN_W && j>=1000) && move== 1)
{
  epine5.affiche=1;
  epine5.x=epine5.x-3;
}
if( move== 1)
{
	epine.x=epine.x-3;
	epine2.x=epine2.x-3;

}


if (p.x>820 )
{//temps=(float)clock()/CLOCKS_PER_SEC;
clear_bitmap(Buffer);
textout_centre_ex(Buffer, font, "Partie terminée!", SCREEN_W/2,150, makecol(255, 0, 100), -1);

//textprintf_ex(Buffer, font, 270, 200, makecol(0,0,255),-1, "vous avez mis %f secondes! ", temps);


if ((float)clock()/CLOCKS_PER_SEC<=10)
{score=100;
textprintf_ex(Buffer,font,270,240,makecol(0,0,255),-1,"SCORE: %d",score); // afficher texte a lecran
}
else if ((float)clock()/CLOCKS_PER_SEC<=20)
{score=80;
textprintf_ex(Buffer,font,270,240,makecol(0,0,255),-1,"SCORE: %d",score);
}
else if ((float)clock()/CLOCKS_PER_SEC<=40) {
score=60;
textprintf_ex(Buffer,font,270,240,makecol(0,0,255),-1,"SCORE: %d",score); }
else if ((float)clock()/CLOCKS_PER_SEC<=60) {
score=40;
textprintf_ex(Buffer,font,270,240,makecol(0,0,255),-1,"SCORE: %d",score); }
else if ((float)clock()/CLOCKS_PER_SEC<=80) {
score=20;
textprintf_ex(Buffer,font,270,240,makecol(0,0,255),-1,"SCORE: %d",score); }
else {
score=0;
textprintf_ex(Buffer,font,270,240,makecol(0,0,255),-1,"SCORE: %d",score); }

textprintf_ex(Buffer,font,270,270,makecol(0,0,255),-1," VIE: %d ",vie); 
textprintf_ex(Buffer,font,270,240,makecol(0,0,255),-1,"SCORE: %d",score); // afficher texte a lecran

}



if(p.y>=SCREEN_H)
{

 dead=1;
}



if( collision(p.x,p.y,p.img_right[0]->w,p.img_right[0]->h, epine.x,epine.y,epine.image->w, epine.image->h)==1)
{ dead=1;}
if( collision(p.x,p.y,p.img_right[0]->w,p.img_right[0]->h, epine2.x,epine2.y,epine.image->w, epine.image->h)==1)
{ dead=1;}

if( collision(p.x,p.y,p.img_right[0]->w,p.img_right[0]->h, epine3.x,epine3.y,epine.image->w, epine.image->h)==1)
{ dead=1;}

if( collision(p.x,p.y,p.img_right[0]->w,p.img_right[0]->h, epine5.x,epine5.y,epine.image1->w, epine.image1->h)==1)
{ dead=1;}


if (dead==1)
{
clear_bitmap(Buffer);
textout_centre_ex(Buffer, font, "You Loose a Life press r to Replay the level  !", SCREEN_W/2,SCREEN_H/2, makecol(255, 0, 100), -1);

}
 
if(dead==1)
{
//makecol(236,15,75)
en=en-1;
//if(vie==2)
//vie=1;
}
if (vie>0){

if(en<=0)
{
vie--;
en=200;}

}else{
clear_bitmap(Buffer);
textout_centre_ex(Buffer, font, "GAME OVER!", SCREEN_W/2,SCREEN_H/2, makecol(236,15,75), -1); }
i=0;
if(key[KEY_R])
       { //vie++; // 10 et 13 . 18 et 19 . 28 et 29
  	 j=0;
	 init_grace(&p);
         dead=0;
	
	epine3.affiche=0;
	epine.x=1050;
	epine.y=230;
	
	epine2.x=3250;
	epine2.y=210;

	epine3.x=2550;
	epine3.y=210;


	epine5.x=2550;
	epine5.y=490;
}    

		//blit Buffer to screen
		blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);

		if (compteur == 10000)
			compteur = 0;
   }
       

	//destroy grace + background
	destroy_grace(&p);
	destroy_background(Background);
	destroy_bitmap(Buffer);
	return (0);
}
END_OF_MAIN();

// module background

BITMAP* load_background_bmp(char chemin_background[])
{
	BITMAP* Background;

	Background=load_bitmap(chemin_background, NULL);
	if(Background == NULL){
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to load image !\n%s\n", allegro_error);
		return (NULL);
	}
	return (Background);
}


void draw_background(BITMAP *Background,BITMAP*Buffer,int j)
{
	blit(Background, Buffer, j, 0, 0, 0, SCREEN_W, SCREEN_H);
}

void destroy_background(BITMAP * Background)
{
	destroy_bitmap(Background);
}

//module grace

void load_grace(Personnage *p) // chargement des images
{
	int i;
	char Buffer[50];
	for (i = 0; i < NB_IMAGES; i++) 
	{
		sprintf(Buffer, "./Pictures/right0%d.bmp", i);
		p->img_right[i] = load_bitmap(Buffer, NULL);
		sprintf(Buffer, "./Pictures/left0%d.bmp", i);
		p->img_left[i] = load_bitmap(Buffer, NULL);
	}
}


void destroy_grace(Personnage *p) //effacer les images
{
	int i;
	for (i = 0; i < NB_IMAGES; i++)
	{
		destroy_bitmap(p->img_right[i]);
		destroy_bitmap(p->img_left[i]);
	}

}

void init_grace(Personnage *p)
{
	p->direction = 0;
	p->x = 2;
	p->y = 100;
}

void move_grace_right(Personnage *p,int *compteur,BITMAP * Background, int *j,int * move)
{   
   variable v;


if((*j)>Background->w-300)
v.x=p->x;
else
v.x=(*j);
   
//v.x=(*j);
   
   v.y=p->y;
   v.w=p->img_right[0]->w;
   v.h=p->img_right[0]->h;
	




   if (key[KEY_RIGHT] && (p->x < SCREEN_W - p->img_right[0]->w) && !collision_background_right( v, Background,0)  ) 
    {




if(((*j)>= 200)&&((*j)<=600))
 {
 p->direction = 0;
  if((p->y<200)&&((*j)<400))
    {
 p->direction=0;
      p->y=p->y-3;
     
    }

if(p->y<300){
  if((*j)>490)
  {
   p->y=p->y+2;
   //p.dir=0;
  }}

 }




	if((*j)<Background->w-SCREEN_W)
             (*j)=(*j)+3;	
        
        /* if( (p->x >300) && ( (*j)<Background->w -SCREEN_W) )
                 p->x=300;
         */ 
          if( (*j)>=Background->w-SCREEN_W)
              {
                p->x=p->x++;
               }  
         
  *compteur+=1;
	   // (p->x)+=1;
	    p->direction = 0; //right
 (*move)=1;
    }
else
 (*move)=0;
}

void move_grace_left(Personnage *p,int *compteur,BITMAP * Background,int j)
{
   variable v;
  
if((j)>Background->w-300)
v.x=p->x;
else
v.x=(j);
   
//v.x=(j);

   v.y=p->y;
   v.w=p->img_right[0]->w;
   v.h=p->img_right[0]->h;
	


if (key[KEY_LEFT] && (p->x > 0 + p->img_left[0]->w )&& !collision_background_left( v, Background,0) ) // 
{
		*compteur+=1;   

		(p->x)-=1;
		p->direction = 1; //left
	}
}

void jump_grace(Personnage *p,BITMAP * Background,int j,int * test)
{
   variable v;
   

if( j>Background->w-SCREEN_W)
  v.x=p->x;
else
   v.x=j;
   
   v.y=p->y;
   v.w=p->img_right[0]->w;
   v.h=p->img_right[0]->h;


if(p->y == 10) 
{
    (*test)=0;
}


if((*test)==1)
{

if (key[KEY_UP] && (p->y >= 10 )&& !collision_background_up(v,Background,0))  // test sur la hauteur du Jump
{
		(p->y)-=10; // monter le personnage avec 6 degré
		 p->direction = 2; // changer la direction pour jump
}

}

if(collision_background_down(v,Background,0) )
{  (*test)=1;}


}
void gravity_grace(Personnage *p,BITMAP * Background,int j)
{ //while (p->y>SCREEN_H-100){
   variable v;
   
if((j)>Background->w-300)
v.x=p->x;
else
  v.x=j;
   
//v.x=(j);

   
   v.y=p->y;
   v.w=p->img_right[0]->w;
   v.h=p->img_right[0]->h;


       if(v.y<=SCREEN_H && !collision_background_down( v, Background,0) ) // test si le personnage arriver a la fin du screen : bas
            p->y=p->y+4;
}//}    

void move_grace(Personnage *p,int *compteur,BITMAP * Background, int *j,int *move,int *test)  // la fonction permettant le movement du personange
{
	move_grace_right(p,compteur,Background,j,move);
	move_grace_left(p,compteur,Background,*j);
	jump_grace(p,Background,*j,test);
	gravity_grace(p,Background,*j);
}

void draw_grace(Personnage p,BITMAP *Buffer, int compteur)
{
	static int last_direction;

	if (p.direction == 0){ //moving right

		draw_sprite(Buffer, p.img_right[compteur % (NB_IMAGES-1) ],p.x, p.y);
		last_direction=0;
	}

	if(p.direction == 1){ //moving left

		draw_sprite(Buffer, p.img_left[compteur % (NB_IMAGES-1) ],p.x, p.y);
		last_direction=1;
	}
	if (p.direction == 2 && last_direction==0) {	//jumping right

		draw_sprite(Buffer, p.img_right[NB_IMAGES - 1],p.x, p.y);
	}
	if (p.direction == 2 && last_direction==1) {	//jumping left

		draw_sprite(Buffer, p.img_left[NB_IMAGES - 1],p.x, p.y);
	}
}

int collision_background_right(variable v,BITMAP* BackgroundCol,int o)
{


   int x=v.x+ v.w;
   int y=v.y + (v.h /2);


 if(get_pixel(BackgroundCol, x,y)==o){

return 1;
}
else{
return 0;
}

}

int collision_background_left(variable v,BITMAP* BackgroundCol,int o){

    
   int x=v.x;
   int y=v.y + (v.h /2);



 if(get_pixel(BackgroundCol, x,y)==o){

return 1;
}
else{
return 0;
}

}

int collision_background_up(variable v,BITMAP* BackgroundCol,int o)
{
   
   int x=v.x+ (v.w /2);
   int y=v.y ;


if(get_pixel(BackgroundCol, x,y)==o){

return 1;
}
else{
return 0;
}
}

int collision_background_down(variable v,BITMAP* BackgroundCol,int o)
{   
   int x=v.x+ (v.w /2);
   int y=v.y + v.h;



if(get_pixel(BackgroundCol, x,y)==o){

return 1;
}
else{
return 0;
}
}

int get_pixel(BITMAP* Buffer,int x,int y)
{
	int tmp;
	tmp=getpixel(Buffer,x,y);
	return((getr(tmp) + getb(tmp) + getg(tmp)) / 3);
}


int collision(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2)
{
if((x1 > x2 + w2-1)|| (y1> y2+ h2-1) || (x2 > x1+ w1-1)||(y2 > y1 + h1-1))
     return 0;

return 1;
}

void soundm()
{

SAMPLE * sound;

if(install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL)) 
{
allegro_message("Sound Error: %s", allegro_error);
allegro_exit();
//return 1;
}

sound = load_wav("./SureShot.wav");
if (!sound)
{
allegro_message("Error reading wav file");
allegro_exit();
//return 1;
}

play_sample(sound, 255, 100,1000, 2);
set_volume(255, 105); 
}



